package com.spring.config.system.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.collect.Maps;
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.AbstractJpaVendorAdapter;
import org.springframework.orm.jpa.vendor.Database;
import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Map;

/**
 * ClassName: DatabaseConfig
 * Desc:
 * Date： 2017/5/9
 * Created：shaom
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(value = "com.spring.config.dao")
public class DatabaseConfig {

    private static final Logger logger = LoggerFactory.getLogger(DatabaseConfig.class);

    @Value("${jdbc.driver}")
    private String jdbcDriver;

    @Value("${jdbc.url}")
    private String dbUrl;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    @Value("${jdbc.maxActive}")
    private Integer maxActive;

    @Value("${jdbc.minidle}")
    private Integer minIdle;

    public String getJdbcDriver() {
        return jdbcDriver;
    }

    @Bean(destroyMethod = "close")
    public DataSource dataSource() {
        logger.info("mysql url:" + dbUrl);
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(jdbcDriver);
        dataSource.setUrl(dbUrl);
        dataSource.setUsername(username);
        dataSource.setPassword(password);

        dataSource.setMaxActive(maxActive);
        dataSource.setMinIdle(minIdle);
        return dataSource;
    }

    @Bean
    public JdbcTemplate jdbcTemplate() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(dataSource());
        return jdbcTemplate;
    }

    @Bean
    public JpaVendorAdapter jpaVendorAdapter() {
        AbstractJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
        adapter.setShowSql(true);
        adapter.setDatabase(Database.MYSQL);
//        adapter.setDatabasePlatform(Database.MYSQL.toString());
        adapter.setGenerateDdl(false);
        return adapter;
    }

    /**
     * 参考SpringBoot JpaBaseConfiguration 的配置
     *
     * @return
     */
    @Bean
    public EntityManagerFactory entityManagerFactory() {
        //        LocalEntityManagerFactoryBean bean = new LocalEntityManagerFactoryBean();
        LocalContainerEntityManagerFactoryBean entityManager = new LocalContainerEntityManagerFactoryBean();
        entityManager.setJtaDataSource(dataSource());
        entityManager.setPackagesToScan("com.spring.config.entity");
        entityManager.setPersistenceProvider(new HibernatePersistenceProvider());
        entityManager.setJpaVendorAdapter(jpaVendorAdapter());
        entityManager.setJpaDialect(new HibernateJpaDialect());

        Map<String, Object> result = Maps.newLinkedHashMap();
        result.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
        result.put("hibernate.hbm2ddl.auto", "update");
        result.put("hibernate.show_sql", true);
        result.put("hibernate.format_sql", true);
//        result.put("hibernate.cache.use_second_level_cache", true);
//        result.put("hibernate.cache.use_query_cache", false);
//        result.put("hibernate.cache.provider_class", "org.hibernate.cache.EhCacheProvider");
        result.put("javax.persistence.transactionType", "jta");
        result.put("hibernate.transaction.coordinator_class", "jta");
        result.put("hibernate.transaction.jta.platform", "org.hibernate.service.jta.platform.internal.WeblogicJtaPlatform");


        entityManager.setJpaPropertyMap(result);
        entityManager.afterPropertiesSet();
        return entityManager.getNativeEntityManagerFactory();
    }

    @Bean
    public EntityManager entityManager() {
        return entityManagerFactory().createEntityManager();
    }

    @Bean
    public PlatformTransactionManager transactionManager() {
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory());
        transactionManager.afterPropertiesSet();
        return transactionManager;
    }
}


